#include "../inc/clist.h"

void CList_Init(CListDef * cthis, void* pUser) {
    assert(MNULL != cthis);


    cthis->pUser = pUser;
    cthis->pLeft = MNULL;
    cthis->pRight = MNULL;

    return;
}

void CList_AppendToLeft(CListDef * cthis, CListDef* pNode) {
    assert(MNULL != cthis);
    assert(MNULL != pNode);

    CListDef* pEnd = cthis;

    while (pEnd->pLeft != MNULL){
        pEnd = pEnd->pLeft;
    };

    pEnd->pLeft = pNode;
    pNode->pRight = pEnd;
}

void CList_AppendToRight(CListDef * cthis, CListDef* pNode) {
    assert(MNULL != cthis);
    assert(MNULL != pNode);

    CListDef* pEnd = cthis;
    
    while (pEnd->pRight != MNULL){
        pEnd = pEnd->pRight;
    };

    pEnd->pRight = pNode;
    pNode->pLeft = pEnd;

}

void CList_InsertToLeft(CListDef* cthis, CListDef* pNode) {
    assert(MNULL != cthis);
    assert(MNULL != pNode);

    if(MNULL == cthis->pLeft){
        cthis->pLeft = pNode;
        pNode->pRight = cthis;
    }else{
        cthis->pLeft->pRight = pNode;
        pNode->pLeft = cthis->pLeft;

        pNode->pRight = cthis;
        cthis->pLeft = pNode;        
    }

    return;
}

void CList_InsertToRight(CListDef* cthis, CListDef* pNode) {
    assert(MNULL != cthis);
    assert(MNULL != pNode);

    if(MNULL == cthis->pRight){
        cthis->pRight = pNode;
        pNode->pLeft = cthis;
        
    }else{
        pNode->pRight = cthis->pRight;
        cthis->pRight->pLeft = pNode; 

        cthis->pRight = pNode;
        pNode->pLeft = cthis;        
    }

    return;
}


void CList_Remove(CListDef* pNode){
    assert(MNULL != pNode);

    
    if(MNULL == pNode->pRight && MNULL == pNode->pLeft)
        return;
    
    if(MNULL == pNode->pRight){
        pNode->pLeft->pRight = MNULL;
        pNode->pLeft = MNULL;
    }else if(MNULL == pNode->pLeft){
        pNode->pRight->pLeft = MNULL;
        pNode->pRight = MNULL;
    }else{
        pNode->pLeft->pRight = pNode->pRight;
        pNode->pRight->pLeft = pNode->pLeft;   
        
        pNode->pLeft = MNULL;
        pNode->pRight = MNULL;
    }
    

    return;
}

mu32 CList_LengthLeft(CListDef* cthis) {
    assert(MNULL != cthis);
    
    mu32 nLength = 0;
    
    while(cthis->pLeft != MNULL){
        nLength++;
        cthis = cthis->pLeft;
    };
    
    return nLength;
}

mu32 CList_LengthRigth(CListDef* cthis) {
    assert(MNULL != cthis);
    
    mu32 nLength = 0;
    
    while(cthis->pRight != MNULL){
        nLength++;
        cthis = cthis->pRight;
    };
    
    return nLength;    
}

CListDef* CList_GetTheMostRight(CListDef* cthis) {
    assert(MNULL != cthis);
    
    while(cthis->pRight != MNULL){
        cthis = cthis->pRight;
    };    
    
    return cthis;
}

CListDef* CList_GetTheMostLest(CListDef* cthis) {
    assert(MNULL != cthis);
    
    while(cthis->pLeft != MNULL){
        cthis = cthis->pLeft;
    };    
    
    return cthis;    
}